package com.icebartech.base.modules.user.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.icebartech.base.modules.user.dto.AppMenuInfoDTO;
import com.icebartech.base.modules.user.dto.AppRoleInfoDTO;
import com.icebartech.base.modules.user.mapper.AppRoleMapper;
import com.icebartech.base.modules.user.model.AppRole;
import com.icebartech.base.modules.user.model.AppRolePermission;
import com.icebartech.base.modules.user.service.AppMenuService;
import com.icebartech.base.modules.user.service.AppRolePermissionService;
import com.icebartech.base.modules.user.service.AppRoleService;
import com.icebartech.core.components.RedisComponent;
import com.icebartech.core.constants.IcebartechConstants;
import com.icebartech.core.modules.AbstractService;
import com.icebartech.core.modules.BaseMapper;
import com.icebartech.core.utils.Cn2PinyinUtil;
import com.icebartech.core.utils.ExtBeanUtils;


@Service
public class AppRoleServiceImpl extends AbstractService implements AppRoleService {
    
    private static Logger logger = LoggerFactory.getLogger(AppRoleServiceImpl.class);
    
    @Autowired
    private AppRoleMapper appRoleMapper;
    
    @Autowired
    private AppRolePermissionService appRolePermissionService;
    
    @Autowired
    private AppMenuService appMenuService;
    
    @Autowired
    private RedisComponent redisComponent;
    
    @Override
    public BaseMapper getBaseMapper() {
        return this.appRoleMapper;
    }
    
    @Override
    public AppRole findRoleByUserId(Long userId) {
        if (userId == null) {
            return null;
        }
        return appRoleMapper.findRoleByUserId(userId);
    }
    
    @Override
    public boolean saveAppRole(AppRoleInfoDTO appRoleInfo) {
        AppRole appRole = new AppRole();
        try {
            String roleKey  = appRoleInfo.getRoleKey();
            ExtBeanUtils.copyProperties(appRole, appRoleInfo);
            if (null == appRole.getId() || appRole.getId() < 1) {
                roleKey = Cn2PinyinUtil.converter2Pinyin(appRole.getRoleName());
                roleKey += "_" + redisComponent.incRedisKey(IcebartechConstants.APP_ROLE, "roleKey");
                appRole.setRoleKey(roleKey);
                appRole.setRoleType("base_role");
                int id = appRoleMapper.insert(appRole);
                if (0 >= id)
                    return false;
            } else {
                AppRole update = appRoleMapper.selectByPrimaryKey(Long.valueOf(appRole.getId()));
                if (null == update)
                    return false;
                roleKey = update.getRoleKey();
                update.setRoleName(appRole.getRoleName());
                update.setRoleDescribe(appRole.getRoleDescribe());
                update.setGmtModified(new Date());
                appRoleMapper.updateByPrimaryKeySelective(update);
            }
            
            // 清除旧权限
            appRolePermissionService.delAppRolePermissionByRoleKey(roleKey);
            // 保存权限
            List<Long> permissionIds = appRoleInfo.getPermissionIds();
            logger.info("permissionIds:{}", permissionIds);
            
            if(CollectionUtils.isNotEmpty(permissionIds)){
            	for (Long permissionId : permissionIds) {
            		AppRolePermission appRolePermission = new AppRolePermission();
            		appRolePermission.setCreator(appRoleInfo.getCreator());
            		appRolePermission.setModifier(appRoleInfo.getModifier());
            		appRolePermission.setRoleKey(roleKey);
            		appRolePermission.setPermissionId(Long.valueOf(permissionId));
            		appRolePermissionService.add(appRolePermission);
            		logger.info("saveAppUserPermission,roleKey:{},permissionId:{}", roleKey, permissionId);
            	}
            }
            // 清除Redis缓存
            //appMenuService.removeMenuFromRedis(roleKey);
            return true;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public PageInfo<AppRoleInfoDTO> findAppRoleByPage(AppRole record, int pageIndex, int pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        
        List<AppRoleInfoDTO> appRoleInfos = new ArrayList<>();
        List<AppRole> appRoles = appRoleMapper.selectBySelective(record);
        PageInfo<AppRole> rolePageInfo = new PageInfo<>(appRoles);
        if(CollectionUtils.isNotEmpty(appRoles)){
        	for (AppRole appRole : appRoles) {
        		try {
        			AppRoleInfoDTO appRoleInfo = assembleRoleInfo(appRole);
        			appRoleInfos.add(appRoleInfo);
        		} catch (Exception e) {
        			logger.error(e.getMessage(), e);
        			continue;
        		}
        	}
        }
        PageInfo<AppRoleInfoDTO> pageInfo = new PageInfo<>();
        pageInfo.setPages(rolePageInfo.getPages());
        pageInfo.setTotal(rolePageInfo.getTotal());
        pageInfo.setList(appRoleInfos);
        return pageInfo;
    }
    
    /**
     * 组装角色扩展对象
     * @param appRole
     * @return
     */
    private AppRoleInfoDTO assembleRoleInfo(AppRole appRole){
    	if(appRole == null){
    		return null;
    	}
    	AppRoleInfoDTO appRoleInfo = new AppRoleInfoDTO();
    	try{
            ExtBeanUtils.copyProperties(appRoleInfo, appRole);
            
            List<String> topPermissionNames = new ArrayList<>();
            List<AppMenuInfoDTO> appMenus = appMenuService.findAppNavbarMenusByRoleKey(appRole.getRoleKey());
            for (AppMenuInfoDTO appMenu : appMenus) {
                topPermissionNames.add(appMenu.getMenuName());
                /*
                if(CollectionUtils.isNotEmpty(appMenu.getChildMenus())){
                	for(AppMenuInfo secondInfo : appMenu.getChildMenus()){
                		topPermissionNames.add(secondInfo.getMenuName());
                	}
                }
                */
            }
            appRoleInfo.setTopPermissionNames(StringUtils.join(topPermissionNames, ","));
            
            List<Long> permissionIds = appRolePermissionService.findPermissionsByRoleKey(appRole.getRoleKey());
            appRoleInfo.setPermissionIds(permissionIds);
    	}catch(Exception e){
    		logger.error(e.getMessage(), e);
    		return null;
    	}
    	return appRoleInfo;
    }
    
    @Override
    public AppRoleInfoDTO getRoleInfoByRoleId(Long roleId) {
        try {
            AppRole appRole = appRoleMapper.selectByPrimaryKey(roleId);
            AppRoleInfoDTO appRoleInfo = assembleRoleInfo(appRole);
            return appRoleInfo;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }
    
    @Override
    public boolean checkPermissions(Long userId, Long permissionId) {
        AppRole appRole = findRoleByUserId(userId);
        List<Long> permissionIds = appRolePermissionService.findPermissionsByRoleKey(appRole.getRoleKey());
        return permissionIds.contains(permissionId);
    }
    
    @Override
    public AppRole findRoleByRoleKey(String roleKey) {
    	return appRoleMapper.selectRoleByRoleKey(roleKey);
    }
    
    @Override
    public boolean deleteRoleByRoleId(Long roleId) {
    	boolean flag = false;
    	AppRole appRole = findById(roleId);
    	if(appRole != null){
    		String roleKey = appRole.getRoleKey();
    		boolean delFlag = appRolePermissionService.delAppRolePermissionByRoleKey(roleKey);
    		if(delFlag){
    			flag = this.deleteById(roleId) > 0;
    		}
    	}
    	return flag;
    }
}
